package com.atguigu.gmall.order.listener;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.Map;

/**
 * 订单微服务监听器 用于接收取消订单的延迟消息
 */
@SuppressWarnings("all")
@Component
public class OrderInfoListener {

    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private RabbitService rabbitService;

    //取消订单
    @RabbitListener(queues = {MqConst.QUEUE_ORDER_CANCEL})
    public void cancelOrder(Long orderId, Message message, Channel channel) {
        try {
            System.out.println("接收到了订单的ID" + orderId);
            System.out.println("接收到了订单的时间" + new Date());
            //存在幂等性问题
            OrderInfo orderInfo = orderInfoService.getOrderInfo(orderId);
            //只有未支付才能取消订单       其他状态不取消订单 如:待发货 已发货
            if (OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())) {
                //TODO 关闭支付宝交易接口 远程调用支付微服务 若关闭成功 则更新订单状态
//                //买家看的
//                orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
//                //后台管理人员看的
//                orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
//                orderInfoMapper.updateById(orderInfo);
                orderInfoService.updateOrderStatus(orderInfo.getId(), ProcessStatus.CLOSED);
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //支付成功后 修改订单状态
    @RabbitListener(bindings = {@QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_PAYMENT_PAY),
            value = @Queue(value = MqConst.QUEUE_PAYMENT_PAY, durable = "true", autoDelete = "false"),
            key = MqConst.ROUTING_PAYMENT_PAY
    )})
    public void updateOrderStatusById(Long orderId, Message message, Channel channel) {
        try {
            System.out.println("接收到的订单Id" + orderId);
            //无幂等性
            //修改订单状态 已支付
            orderInfoService.updateOrderStatus(orderId, ProcessStatus.PAID);
            //发消息  订单微服务(订单主表 1 : 订单详情表 N)发消息给仓库微服务(库存工作单表 1 : 库存工作单详情表N)
            //JSON格式
            Map initWareInfo = orderInfoService.initWareOrder(orderId);
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_WARE_STOCK,
                    MqConst.ROUTING_WARE_STOCK, JSONObject.toJSONString(initWareInfo));
            //修改订单状态 修改已支付改为已通知仓储
            orderInfoService.updateOrderStatus(orderId, ProcessStatus.NOTIFIED_WARE);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //接收仓库扣减库存是否成功

    /**
     * orderId	订单系统的订单ID
     * status	 状态： ‘DELEVERED’ 已减库存
     * 状态： ‘OUT_OF_STOCK’库存超卖
     */
    @RabbitListener(bindings = {@QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_WARE_ORDER),
            value = @Queue(value = MqConst.QUEUE_WARE_ORDER, durable = "true", autoDelete = "false"),
            key = MqConst.ROUTING_WARE_ORDER
    )})
    //生产者发送的是json 包含了orderId和status
    public void updateOrderStatus(String result, Message message, Channel channel) {
        try {
            System.out.println("接收到的result = " + result);
            Map map = JSONObject.parseObject(result, Map.class);
            if ("DELEVERED".equals(map.get("status"))){
                //扣减库存成功 修改订单的状态
                //修改订单状态为 待发货
                //Object类型无法直接转换为Long类型 Object->Integer->Long或者Object->String->Long
                orderInfoService.updateOrderStatus(Long.parseLong(
                        String.valueOf(map.get("orderId"))),ProcessStatus.WAITING_DELEVER);
            }else{
                //库存超卖
                orderInfoService.updateOrderStatus(Long.parseLong(
                        String.valueOf(map.get("orderId"))),ProcessStatus.STOCK_EXCEPTION);
                //打印日志转人工
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
